package com.common.project.util;
import cn.hutool.core.codec.Base64;
import cn.hutool.json.JSONUtil;
import com.common.project.common.ClientParams;
import com.common.project.enums.I18nEnum;
import com.common.project.exception.BaseException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.util.WebUtils;

/**
 * @ClassName WebUtil
 * @Description
 * @Author jiangshicun@bicai365.com
 * @Date 2019/6/20 13:16
 */
public class WebUtil {
    private static final Logger log = LoggerFactory.getLogger(WebUtil.class);
    private static final String BASIC_ = "Basic ";
    private static final String UNKNOWN = "unknown";

    public WebUtil() {
    }

    public static String URLEncode(String url) {
        String encodedStr = null;

        try {
            encodedStr = URLEncoder.encode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return encodedStr;
    }

    public static String URLDecode(String url) {
        String encodedStr = null;

        try {
            encodedStr = URLDecoder.decode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return encodedStr;
    }

    public static String getCookieVal(String name) {
        HttpServletRequest request = getRequest();
        Assert.notNull(request, "request from RequestContextHolder is null");
        return getCookieVal(request, name);
    }

    public static String getCookieVal(HttpServletRequest request, String name) {
        Cookie cookie = WebUtils.getCookie(request, name);
        return cookie != null ? cookie.getValue() : null;
    }

    public static void removeCookie(HttpServletResponse response, String key) {
        setCookie(response, key, (String)null, 0);
    }

    public static void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
        Cookie cookie = new Cookie(name, value);
        cookie.setPath("/");
        cookie.setMaxAge(maxAgeInSeconds);
        cookie.setHttpOnly(true);
        response.addCookie(cookie);
    }

    public static HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    public static HttpServletResponse getResponse() {
        return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
    }

    public static void renderJson(HttpServletResponse response, Object result) {
        renderJson(response, result, "application/json;charset=UTF-8");
    }

    public static void renderJson(HttpServletResponse response, Object result, String contentType) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType(contentType);

        try {
            PrintWriter out = response.getWriter();
            Throwable var4 = null;

            try {
                out.append(JSONUtil.toJsonStr(result));
            } catch (Throwable throwable) {
                var4 = throwable;
                throw throwable;
            } finally {
                if (out != null) {
                    if (var4 != null) {
                        try {
                            out.close();
                        } catch (Throwable var13) {
                            var4.addSuppressed(var13);
                        }
                    } else {
                        out.close();
                    }
                }

            }
        } catch (IOException var16) {
            log.error(var16.getMessage(), var16);
        }

    }

    public static String getIP() {
        return getIP(getRequest());
    }

    public static ClientParams getClientParams() {
        ClientParams clientParams = null;
        HttpServletRequest request = getRequest();
        String json = request.getHeader("clientParams");
        if (StringUtils.isEmpty(json)) {
            log.error("Header object of clientParams is not found");
            return clientParams;
        } else {
            try {
                clientParams = (ClientParams)JSONUtil.toBean(json,ClientParams.class);

                if (clientParams != null) {
                    I18nEnum[] i18nEnums = I18nEnum.values();
                    String language = clientParams.getLanguage();
                    boolean status = true;
                    I18nEnum[] var6 = i18nEnums;
                    int var7 = i18nEnums.length;

                    for(int var8 = 0; var8 < var7; ++var8) {
                        I18nEnum i18nEnum = var6[var8];
                        if (i18nEnum.getCode().equalsIgnoreCase(language)) {
                            status = false;
                            break;
                        }
                    }

                    language = status ? I18nEnum.ZH_CN.getCode() : language;
                    clientParams.setLanguage(language);
                }
            } catch (IllegalArgumentException var10) {
                log.error("ClientParams convert error!", var10);
            }

            log.warn("client params:{}", clientParams);
            return clientParams;
        }
    }

    public static String getIP(HttpServletRequest request) {
        Assert.notNull(request, "HttpServletRequest is null");
        String ip = request.getHeader("X-Requested-For");
        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }

        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }

        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }

        if (StringUtils.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        return StringUtils.isBlank(ip) ? null : ip.split(",")[0];
    }

    public static String[] getClientId(ServerHttpRequest request) {
        try {
            String header = request.getHeaders().getFirst("Authorization");
            if (header != null && header.startsWith("Basic ")) {
                byte[] base64Token = header.substring(6).getBytes("UTF-8");

                byte[] decoded;
                try {
                    decoded = Base64.decode(base64Token);
                } catch (IllegalArgumentException var6) {
                    throw new BaseException("Failed to decode basic authentication token");
                }

                String token = new String(decoded, StandardCharsets.UTF_8);
                int delim = token.indexOf(":");
                if (delim == -1) {
                    throw new BaseException("Invalid basic authentication token");
                } else {
                    return new String[]{token.substring(0, delim), token.substring(delim + 1)};
                }
            } else {
                throw new BaseException("请求头中client信息为空");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return null;

    }
}
